package com.ctz.commonframe.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.text.TextUtils;

public class SharedPrefrencesUtil {
	private static final String FILE_NAME_SUFIX = "_share";
	private static Context context;
	private static String packageName;

	public static void init(Context context) {
		SharedPrefrencesUtil.context = context;
		packageName = context.getPackageName();
	}

	/**
	 * 保存数据
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            数据，类型为（String, Integer, Long, Float, Boolean）
	 */
	public static void put(String key, Object value) {
		putAboutUser(null, key, value);
	}

	/**
	 * 保存用户相关的数据
	 * 
	 * @param userId
	 *            用户id，也可以是其他唯一标识
	 * @param key
	 *            键
	 * @param value
	 *            数据，类型为（String, Integer, Long, Float, Boolean）
	 */
	public static void putAboutUser(String userId, String key, Object value) {
		Editor editor = getEditor();
		String realKey = TextUtils.isEmpty(userId) ? key : key + "_" + userId;
		if (value == null || value instanceof String) {
			editor.putString(realKey, (String) value);
		} else if (value instanceof Integer) {
			editor.putInt(realKey, (Integer) value);
		} else if (value instanceof Boolean) {
			editor.putBoolean(realKey, (Boolean) value);
		} else if (value instanceof Float) {
			editor.putFloat(realKey, (Float) value);
		} else if (value instanceof Long) {
			editor.putLong(realKey, (Long) value);
		}
		SharedPreferencesCompat.apply(editor);
	}

	/**
	 * 保存用户相关的字符串数组
	 *
	 * @param userId
	 *            用户id，也可以是其他唯一标识
	 * @param key
	 *            键
	 * @param value
	 *            数据，类型为Set<String>
	 */
	public static void putSetAboutUser(String userId, String key, Set<String> set) {
		Editor editor = getEditor();
		String realKey = TextUtils.isEmpty(userId) ? key : key + "_" + userId;
		editor.putStringSet(realKey, set);
		SharedPreferencesCompat.apply(editor);
	}

	/**
	 * 获取数据
	 * 
	 * @param key
	 *            键
	 * @param defaultObject
	 *            默认值,类型为(String, Integer, Long, Float, Boolean)
	 * @return
	 */
	public static Object get(String key, Object defaultObject) {
		return getAboutUser(null, key, defaultObject);
	}

	/**
	 * 获取用户相关数据
	 * 
	 * @param userId
	 *            用户id，也可以是其他唯一标识
	 * @param key
	 *            键
	 * @param defaultObject
	 *            默认值,类型为(String, Integer, Long, Float, Boolean)
	 * @return
	 */
	public static Object getAboutUser(String userId, String key, Object defaultObject) {
		String realKey = TextUtils.isEmpty(userId) ? key : key + "_" + userId;
		SharedPreferences sp = getPreferences();
		if (defaultObject == null || defaultObject instanceof String) {
			return sp.getString(realKey, (String) defaultObject);
		} else if (defaultObject instanceof Integer) {
			return sp.getInt(realKey, (Integer) defaultObject);
		} else if (defaultObject instanceof Boolean) {
			return sp.getBoolean(realKey, (Boolean) defaultObject);
		} else if (defaultObject instanceof Float) {
			return sp.getFloat(realKey, (Float) defaultObject);
		} else if (defaultObject instanceof Long) {
			return sp.getLong(realKey, (Long) defaultObject);
		}

		return null;
	}

	/**
	 * 获取用户相关字符串数组
	 *
	 * @param userId
	 *            用户id，也可以是其他唯一标识
	 * @param key
	 *            键
	 * @return
	 */
	public static Set<String> getSetAboutUser(String userId, String key) {
		String realKey = TextUtils.isEmpty(userId) ? key : key + "_" + userId;
		SharedPreferences sp = getPreferences();
		return sp.getStringSet(realKey, null);
	}

	/**
	 * 返回所有的键值对
	 *
	 * @return
	 */
	public static Map<String, ?> getAll() {
		return getPreferences().getAll();
	}

	/**
	 * 清除所有数据
	 */
	public static void clearAll() {
		SharedPreferencesCompat.apply(getEditor().clear());
	}

	public static void clearKey(String key){
		getEditor().remove(key).commit();
	}

	public static void clearKeyAboutUser(String userId, String key){
		getEditor().remove(key + "_" + userId).commit();
	}

	/**
	 * 清除所有用户相关数据
	 * 
	 * @param userId
	 */
	public static void clearAllAboutUser(String userId) {
		Editor editor = getEditor();
		Map<String, ?> map = getAll();
		if (map != null && map.size() > 0) {
			for (String key : map.keySet()) {
				if (key.endsWith(userId)) {
					editor.remove(key);
				}
			}
			SharedPreferencesCompat.apply(editor);
		}
	}

	private static SharedPreferences getPreferences() {
		return context.getSharedPreferences(packageName + FILE_NAME_SUFIX, Context.MODE_PRIVATE);
	}

	private static Editor getEditor() {
		return getPreferences().edit();
	}

	/**
	 * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
	 * 目的是尽可能的使用apply代替commit，因为commit方法是同步的，apply方法是异步的，很多时候的commit操作都是UI线程中，
	 * 毕竟是IO操作，尽可能异步
	 */
	private static class SharedPreferencesCompat {
		private static final Method sApplyMethod = findApplyMethod();

		/**
		 * 反射查找apply的方法
		 * 
		 * @return
		 */
		@SuppressWarnings({ "unchecked", "rawtypes" })
		private static Method findApplyMethod() {
			try {
				Class clz = SharedPreferences.Editor.class;
				return clz.getMethod("apply");
			} catch (NoSuchMethodException e) {
			}

			return null;
		}

		/**
		 * 如果找到则使用apply执行，否则使用commit
		 * 
		 * @param editor
		 */
		public static void apply(SharedPreferences.Editor editor) {
			try {
				if (sApplyMethod != null) {
					sApplyMethod.invoke(editor);
					return;
				}
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			}
			editor.commit();
		}
	}
}
